#include <stdlib.h>
#include <stdio.h>
#include "util.h"

int iErrno;

void print_a(int a[], int n, FILE *f)
{
    int i;
    FILE * ff = NULL;

    if (a == NULL)
	return;

    if (f)
    {
	ff = f;
    }
    else
    {
	ff = stdout;
    }
    if (n <= 0)
    {
	fprintf(ff, "%d elements: EMPTY!\n", n);
	return;
    }

    fprintf(ff, "%d elements:\n\t", n);
    for (i = 0; i < n; i++)
    {
	fprintf(ff, "%d\t", a[i]);
	if (i && ((i+1) % ELEMENTS_PER_LINE) == 0)
	{
	    fprintf(ff, "\n\t");
	}
    }
    fprintf(ff, "\n");

    fflush(ff);
}

void print_a_range(int a[], int p, int r, FILE *f)
{
    int i;
    FILE *ff = NULL;

    if (a == NULL || p > r)
	return;
    if (f)
    {
	ff = f;
    }
    else
    {
	ff = stdout;
    }

    fprintf(ff, "%d elements:\n\t", r-p+1);
    for (i = 0; i < r - p + 1; i++)
    {
	fprintf(ff, "%d\t", a[p+i]);
	if (i && ((i+1) % ELEMENTS_PER_LINE) == 0)
	{
	    fprintf(ff, "\n\t");
	}
    }
    fprintf(ff, "\n");

    fflush(ff);
}

void swap(int *a, int *b)
{
    int t;

    if (a != b)
    {
	// NOTE: otherwise just set the element to 0
	*a = *a ^ *b;
	*b = *a ^ *b;
	*a = *a ^ *b;
    }
    else
    {
	t = *a;
	*a = *b;
	*b = t;	
    }
}

/*
void bubblesort(int a[], int n)
{
    int i, j;

    for (i = 0; i < n - 1; i++)
    {
	for (j = i + 1; j < n; j++)
	{
	    if (a[j] < a[i])
		swap(&a[i], &a[j]);
	}
    }
}
*/

int 
permute_in_place(void *pA, const int elem_size, const int p, const int r)
{
    void *pTmp;
    int i, j;

    if (p >= r)
    {
        iErrno = EINVAL;
        return -1;
    }

    if ((pTmp = malloc(elem_size)) == NULL)
    {
        iErrno = ENOMEM;
        return -1;
    }

    srand(time(NULL));
    for (i = p; i <= r; i++)
    {
        j = rand() % (r-p+1);
        memcpy(pTmp, pA+elem_size*j, elem_size);
        memcpy(pA+elem_size*j, pA+elem_size*i, elem_size);
        memcpy(pA+elem_size*i, pTmp, elem_size);
    }

    free(pTmp);

    return 0;
}

// array should be sorted before invoke this function
int
not_uniq(int a[], int n)
{
    int i;

    for (i = 0; i < n-1; i++)
        if (a[i] == a[i+1])
            return 1;

    return 0;
}
